package com.gurumades.jsonform.client.forms;

import java.util.HashMap;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.TextBoxBase;
import com.google.gwt.user.client.ui.Widget;

public class FormItemViewTextInput extends FormItemViewAbstract {

	private static final BinderInput binderInput = GWT
			.create(BinderInput.class);

	@UiTemplate("FormItemViewTextInput.ui.xml")
	interface BinderInput extends UiBinder<Widget, FormItemViewTextInput> {
	}

	private static final BinderSelect binderSelect = GWT
			.create(BinderSelect.class);

	@UiTemplate("FormItemViewTextSelect.ui.xml")
	interface BinderSelect extends UiBinder<Widget, FormItemViewTextInput> {
	}

	private static final BinderArea binderArea = GWT.create(BinderArea.class);

	@UiTemplate("FormItemViewTextArea.ui.xml")
	interface BinderArea extends UiBinder<Widget, FormItemViewTextInput> {
	}

	protected String widget;

	HashMap<String, String> optionsValues = new HashMap<String, String>();

	HashMap<String, RadioButton> radios = new HashMap<String, RadioButton>();

	public FormItemViewTextInput(String widget) {
		if (widget.equals("input")) {
			initWidget(binderInput.createAndBindUi(this));
		} else if (widget.equals("select")) {
			initWidget(binderSelect.createAndBindUi(this));
		} else if (widget.equals("area")) {
			initWidget(binderArea.createAndBindUi(this));
		} else if (widget.equals("radio")) {
			initWidget(binderInput.createAndBindUi(this));
		}

		addStyleName("jsonForm-FormItem");
		addStyleName("jsonForm-FormItem-" + widget);
		this.widget = widget;
	}

	@Override
	public void setData(JSONValue object) {
		if (object.isObject() != null) {
			object = object.isObject().get("value");
			if (widget.equals("input")) {
				_setDataTextBox(object);
			} else if (widget.equals("select")) {
				_setDataListBox(object);
			} else if (widget.equals("area")) {
				_setDataTextBox(object);
			} else if (widget.equals("radio")) {
				_setDataRadioBox(object);
			}
		}

	}

	@Override
	public boolean isValueEmpty() {
		return getValue().get("value").isString().stringValue().isEmpty();
	}

	@Override
	public JSONObject getValue() {
		JSONObject object = new JSONObject();
		if (widget.equals("input")) {
			object.put("value", new JSONString(((TextBox) value).getText()));
		} else if (widget.equals("select")) {
			ListBox lb = (ListBox) value;
			int index = lb.getSelectedIndex();
			if (index >= 0) {
				object.put("value", new JSONString(lb.getValue(index)));
			} else {
				object.put("value", new JSONString(""));
			}

		} else if (widget.equals("area")) {
			object.put("value", new JSONString(((TextBoxBase) value).getText()));
		} else if (widget.equals("radio")) {
			object.put("value", new JSONString(""));
		}

		return object;
	}

	public void _setDataTextBox(JSONValue object) {
		((TextBoxBase) this.value).setText(object.isString() != null ? object
				.isString().stringValue() : null);
	}

	public void _setDataListBox(JSONValue object) {
		ListBox list = (ListBox) this.value;
		String str = object.isString() != null ? object.isString()
				.stringValue() : null;
		if (str == null) {
			return;
		}
		for (int i = 0; i < list.getItemCount(); i++) {
			if (list.getValue(i).equals(str)) {
				list.setSelectedIndex(i);
			}
		}
	}

	public void _setDataRadioBox(JSONValue object) {
		String str = object.isString() != null ? object.isString()
				.stringValue() : null;
		if (str != null) {
			for (String key : radios.keySet()) {
				if (str.equals(key)) {
					RadioButton rb = radios.get(key);
					rb.setValue(true);
					break;
				}
			}
		}
	}

	@Override
	public void initFormItem(JSONValue value, JSONObject formItemSettings) {
		super.initFormItem(value, formItemSettings);

		radios.clear();

		if (widget.equals("select") || widget.equals("radio")) {
			String allowed = this.extras.get("options");

			Widget wgt = this.value;
			Element parentElement = wgt.getParent().getElement();

			boolean first = true;
			if (allowed != null) {
				String[] allowedValues = allowed.split(",");

				for (int i = 0; i < allowedValues.length; i++) {
					optionsValues.put("", "Select a value");

					String key = allowedValues[i];
					String label = allowedValues[i];

					String[] keyValue = allowedValues[i].split("=");
					if (keyValue.length == 2) {
						optionsValues.put(keyValue[0].trim(),
								keyValue[1].trim());
						key = keyValue[0].trim();
						label = keyValue[1];
					} else {
						optionsValues.put(allowedValues[i].trim(),
								allowedValues[i].trim());
					}

					if (widget.equals("select")) {
						if (first) {
							((ListBox) this.value)
									.addItem("Select a value", "");
							first = false;
						}

						((ListBox) this.value).addItem(allowedValues[i], key);
					}

					if (widget.equals("radio")) {
						RadioButton rb = new RadioButton(this.fieldID, label);
						rb.setFormValue(key);
						parentElement.appendChild(rb.getElement());
						wgt.setVisible(false);
						radios.put(allowedValues[i], rb);
					}
				}
			}

		} else if (widget.equals("area")) {
			String cols = this.extras.get("cols");
			String rows = this.extras.get("rows");

			TextArea area = (TextArea) this.value;
			try {
				area.setCharacterWidth(Integer.parseInt(cols));
				area.setVisibleLines(Integer.parseInt(rows));
			} catch (Exception e) {
			}
		} else if (widget.equals("input")) {
			String cols = this.extras.get("width");

			try {
				TextBox input = (TextBox) this.value;
				input.setVisibleLength(Integer.parseInt(cols));
			} catch (Exception e) {
			}
		}
	}

}
